{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1331faa1",
   "metadata": {},
   "source": [
    "可以在[Bookshop.org](https://bookshop.org/a/98697/9781098155438) 和\n",
    "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)获取纸制版和电子版的*Think Python 3e*."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a14edb7e",
   "metadata": {
    "tags": []
   },
   "source": [
    "# 第1章:欢迎！\n",
    "\n",
    "这是由Allen B. Downey编写的[*Think Python*第3版](https://greenteapress.com/wp/think-python-3rd-edition)的第1章。\n",
    "\n",
    "如果你不熟悉Jupyter笔记，[点击这里](jupyter_intro.ipynb)查看简短的介绍。\n",
    "\n",
    "如果你想在Colab上运行本笔记，[点击这里](https://colab.research.google.com/github/AllenDowney/ThinkPython/blob/v3/chapters/chap01.ipynb)进行访问。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b4a1f57",
   "metadata": {
    "tags": []
   },
   "source": [
    "下面的单元格会下载与本书配套运行的代码。你目前不需要理解这段代码，但你需要在运行笔记其他代码之前运行此代码。\n",
    "\n",
    "记住，你可以选择代码单元格，按下单元格前面的执行按钮（三角形图标），或者按住`Shift`并按下`Enter`，执行单元格。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "213f9d96",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from os.path import basename, exists\n",
    "\n",
    "def download(url):\n",
    "    filename = basename(url)\n",
    "    if not exists(filename):\n",
    "        from urllib.request import urlretrieve\n",
    "\n",
    "        local, _ = urlretrieve(url, filename)\n",
    "        print(\"Downloaded \" + str(local))\n",
    "    return filename\n",
    "\n",
    "download('https://gitee.com/regentsai/Think_Python_3e_CN/blob/master/thinkpython.py');\n",
    "\n",
    "import thinkpython"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "333a6fc9",
   "metadata": {
    "tags": []
   },
   "source": [
    "# 编程是一种思维方式\n",
    "\n",
    "本书的第一个目标是教你如何用Python进行编程。但是学习编程意味着学习一种新的思维方式，因此本书的第二个目标是帮助你像计算机科学家一样思考。\n",
    "\n",
    "这种思维方式结合了数学，工程学以及自然科学的部分最佳特性。与数学家一样，计算机科学家使用形式语言表示概念--尤其是计算概念；与工程师一样，计算机科学家设计组件，组装成系统，并对可选方案进行权衡；与科学家一样，计算机科学家观察复杂系统的行为，形成假设并进行测试。\n",
    "\n",
    "我们会从编程的最基础元素开始，然后逐步学习。本章我们将看到Python是如何表示数字，字母和单词的。你也会学习如何执行算术运算。\n",
    "\n",
    "你也会开始学习关于编程的词汇，包括运算符(operator)，表达式(expression)，值(value)，类型(type)等等术语。\n",
    "\n",
    "这些词汇很重要，你需要它们来理解本书的剩余部分，与其他程序员交流，以及学习和理解虚拟助手。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a371aea3",
   "metadata": {},
   "source": [
    "## 算术运算符\n",
    "\n",
    "**算术运算符**(也可译为算术操作符，arithmetic operator)是表示算术运算的符号。例如，加号`+`执行加法运算。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2568ec84",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "30 + 12"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc0e7ce8",
   "metadata": {},
   "source": [
    "减号`-`是执行减法的运算符。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c4e75456",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "43 - 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63e4e780",
   "metadata": {},
   "source": [
    "星号`*`执行乘法运算。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "022a7b16",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "6 * 7"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "508c1cba",
   "metadata": {},
   "source": [
    "译注:与数学表示方式不同,Python不允许省略乘法中的星号,初学者通常会丢失这个星号."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6192d13",
   "metadata": {},
   "source": [
    "正斜杠`/`(forward slash)执行除法运算:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "05ae1098",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42.0"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "84 / 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "641ad233",
   "metadata": {},
   "source": [
    "注意除法的结果是`42.0`而不是`42`。因为Python中有两种数字类型：\n",
    "\n",
    "- **整数**(integers)表示数字没有分数或小数部分；\n",
    "- **浮点数**(floating-point numbers)表示整数以及有小数点的数字。\n",
    "\n",
    "如果你对两个整数进行加法，减法或乘法，结果依然是整数。但如果你将两个整数相除，结果是浮点数。\n",
    "\n",
    "Python提供另一个运算符`//`，执行**整数除法**，整数除法的结果总是整数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4df5bcaa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "84 // 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2a620ab",
   "metadata": {},
   "source": [
    "整数除法也叫作“地板除法”(floor division),因为它总是向下（朝着“地板”）取整。\n",
    "\n",
    "译注：即使对有负数参与的地板除法，依然如此。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "ef08d549",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "85 // 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41e2886a",
   "metadata": {},
   "source": [
    "最后，`**`运算符执行幂运算；也即`m ** n`计算m自乘n次的结果："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "df933e80",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "49"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "7 ** 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2502fb6",
   "metadata": {},
   "source": [
    "在一些其他语言中使用增字符号`^`(caret)进行幂运算，但在Python中是称为XOR异或运算的位运算符。如果你不熟悉位运算符，下面的结果可能难以理解："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "306b6b88",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "7 ^ 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30078370",
   "metadata": {},
   "source": [
    "在本书中不会介绍位运算符，但你可以在<http://wiki.python.org/moin/BitwiseOperators>上了解."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f5b7e97",
   "metadata": {},
   "source": [
    "## 表达式\n",
    "\n",
    "在当前阶段，若干运算符和数字的组合叫作表达式(**expression**)。表达式可以包含任意数量的运算符和数字。例如，这是包含两个运算符的表达式："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "6e68101d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "6 + 6 ** 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e95039c",
   "metadata": {},
   "source": [
    "注意幂运算在加法之前执行。Python对运算符的运算顺序与你在数学课上学过的类似：幂运算在乘法和除法之前执行，乘法和除法在加法和减法之前执行。\n",
    "\n",
    "在下面的例子中，乘法在加法之前执行。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ffc25598",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "12 + 5 * 6"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "914a60d8",
   "metadata": {},
   "source": [
    "如果你想要先执行加法运算，你可以使用括号包围。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "8dd1bd9a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "102"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(12 + 5) * 6"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67ae0ae9",
   "metadata": {},
   "source": [
    "每个表达式有一个**值**(value)。例如，表达式`6 * 7`的值为`42`。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "caebaa51",
   "metadata": {},
   "source": [
    "## 算术函数\n",
    "\n",
    "除了算术运算符，Python提供一些处理数字的**函数**(function)。例如`round`函数接受一个浮点数，将其取整到最近的整数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "1e3d5e01",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(42.4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "d1b220b9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "43"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(42.6)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5738b4b",
   "metadata": {},
   "source": [
    "`abs`函数计算数字的绝对值。正数的绝对值是它本身。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "ff742476",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "abs(42)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e518494a",
   "metadata": {},
   "source": [
    "负数的绝对值是正数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "9247c1a3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "abs(-42)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6969ce45",
   "metadata": {},
   "source": [
    "当我们像上面一样使用函数时，我们称正在**调用**(calling)该函数。调用函数的表达式叫作**函数调用**。当你调用函数时需要使用括号。如果没有包含括号，你将收到错误信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5a73bfd5",
   "metadata": {
    "tags": []
   },
   "source": [
    "注意: 下面单元格使用Jupyter的“魔术命令”`%%expect`，表明我们预期这个单元格的代码将产生错误。关于这个话题，参见[Jupyter notebook 介绍](jupyter_intro.ipynb)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "4674b7ca",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (3827346253.py, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  Cell \u001b[0;32mIn[17], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m    abs 42\u001b[0m\n\u001b[0m        ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "%%expect SyntaxError\n",
    "\n",
    "abs 42"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d356f1b",
   "metadata": {},
   "source": [
    "你可以忽略这个信息的第一行，它不包含我们目前需要理解的信息。第二行是包含错误的代码，在下方有增字符号(`^`)指出错误发生的地方。\n",
    "\n",
    "最后一行指出这是一个**语法错误**(syntax error),表示表达式的结构存在错误。对于这个例子，问题在于函数调用需要使用括号。\n",
    "\n",
    "让我们看看如果不提供括号和值会发生什么。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "7d3e8127",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<function abs(x, /)>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "abs"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94478885",
   "metadata": {},
   "source": [
    "函数名自身是一个合法的表达式，有自己的值。函数名的值指出`abs`是一个函数，并包含一些额外信息，我将稍后进行解释。\n",
    "\n",
    "译注：中文读者需要注意，Python语法中必须使用半角符号，`（）“”‘’【】，！`的错误使用是语法错误的常见原因。使用英文输入法输入这些符号。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "61bff845",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid character '（' (U+FF08) (2785236529.py, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  Cell \u001b[0;32mIn[19], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m    abs（42）\u001b[0m\n\u001b[0m       ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid character '（' (U+FF08)\n"
     ]
    }
   ],
   "source": [
    "%%expect SyntaxError\n",
    "\n",
    "abs（42）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "31a85d17",
   "metadata": {},
   "source": [
    "## 字符串\n",
    "\n",
    "除了数字，Python也可以表示一串字母，称为**字符串**(string),因为字母像项链上的珍珠一样串在一起。要表示字符串，可以将一串字母用单引号包围。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "bd8ae45f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello'"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'Hello'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d20050d8",
   "metadata": {},
   "source": [
    "使用双引号也是合法的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "01d0055e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'world'"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"world\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "76f5edb7",
   "metadata": {},
   "source": [
    "双引号字符串让你能够简单的表示含有单引号的字符串，反之亦然。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "0295acab",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"it's a small \""
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"it's a small \""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf040d5f",
   "metadata": {},
   "source": [
    "译注:用单引号包围的字符串,如果中间包含单引号且没有进行处理,将会导致语法错误."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d62d4b1c",
   "metadata": {},
   "source": [
    "字符串可以包含空格，标点符号和数字。\n",
    "\n",
    "译注：与常见表达式不同，字符串内部可以包含全角符号。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "cf918917",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Well, '"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'Well, '"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "3d3604c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好，“世界”！'"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'你好，“世界”！'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ad47f7a",
   "metadata": {},
   "source": [
    "加号运算符`+`可以处理字符串，将两个字符串连成一个字符串，称为**拼接**(concatenation)。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "aefe6af1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"Well, it's a small world.\""
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'Well, ' + \"it's a small \" + 'world.'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ad969a3",
   "metadata": {},
   "source": [
    "星号运算符`*`也能处理字符串，将一个字符串重复拼接多次。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "42e9e4e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Spam, Spam, Spam, Spam, '"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'Spam, ' * 4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dfba16a5",
   "metadata": {},
   "source": [
    "其他算术运算符不能处理字符串。\n",
    "\n",
    "Python提供一个函数`len`，能够计算字符串的长度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "a5e837db",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len('Spam')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "bae1a672",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len('你好！')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d91e00b3",
   "metadata": {},
   "source": [
    "注意`len`计算引号内部的字母数量，不包含外部的引号。\n",
    "\n",
    "当你创建字符串，确保使用直引号(',\")。反引号(backtick,`)将导致语法错误。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "e3f65f19",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (1580190030.py, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  Cell \u001b[0;32mIn[28], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m    `Hello`\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "%%expect SyntaxError\n",
    "\n",
    "`Hello`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40d893d1",
   "metadata": {},
   "source": [
    "智能引号（也称弯引号）也是非法的字符串引号。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "a705b980",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid character '‘' (U+2018) (232449189.py, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  Cell \u001b[0;32mIn[29], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m    ‘Hello’\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid character '‘' (U+2018)\n"
     ]
    }
   ],
   "source": [
    "%%expect SyntaxError\n",
    "\n",
    "‘Hello’"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5471d4f8",
   "metadata": {},
   "source": [
    "## 值和类型\n",
    "\n",
    "目前我们看到了3种值：\n",
    "\n",
    "- `2`是整数；\n",
    "- `42.0`是浮点数；\n",
    "- `'Hello'`是字符串。\n",
    "\n",
    "值的种类称为**类型**(type)。每个值都有类型，或者有时我们说这个值“属于”某个类型。\n",
    "\n",
    "Python提供`type`函数，告诉你任何值的类型。整数的类型是`int`。\n",
    "\n",
    "译注：技术上讲`type`并不是函数。但是Python广泛采用“鸭子类型”的思想，“如果一个东西看起来像鸭子，叫起来像鸭子，那么它就是鸭子”。在本节中`type`可以跟随括号和一个参数，执行一些运算并返回一个结果，与函数没有区别。在不导致误解的情况下，有些术语可能会混用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "3df8e2c5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b137814c",
   "metadata": {},
   "source": [
    "浮点数的类型是`float`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "c4732c8d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "float"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(42.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "266dea4e",
   "metadata": {},
   "source": [
    "字符串的类型是`str`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "8f65ac45",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "str"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type('Hello, World!')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "76d216ed",
   "metadata": {},
   "source": [
    "`int`, `float`和`str`类型可以当成函数使用。例如，`int`可以接受一个浮点数并转换为整数（总是向下取整）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "84b22f2f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int(42.9)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcd8d114",
   "metadata": {},
   "source": [
    "`float`可以将整数转换为浮点数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "9b66ee21",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42.0"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float(42)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eda70b61",
   "metadata": {},
   "source": [
    "下面的例子可能让人疑惑，如果你将数字放到引号里，你会得到什么？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "f64e107c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'126'"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'126'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fdded653",
   "metadata": {},
   "source": [
    "它看起来像数字，但其实是一个字符串。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "609a8153",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "str"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type('126')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2683ac35",
   "metadata": {},
   "source": [
    "如果你想要像数字一样使用字符串，你可能收到错误。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "1cf21da4",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unsupported operand type(s) for /: 'str' and 'int'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31mTypeError\u001b[0m\u001b[0;31m:\u001b[0m unsupported operand type(s) for /: 'str' and 'int'\n"
     ]
    }
   ],
   "source": [
    "%%expect TypeError\n",
    "\n",
    "'126' / 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32c11cc4",
   "metadata": {},
   "source": [
    "这个例子产生类型错误`TypeError`，表示在表达式中的值（此处叫作**运算数,运算对象**,operands）的类型存在错误。\n",
    "\n",
    "该错误指出`/`运算符不支持对`str`与`int`类型进行运算.\n",
    "\n",
    "如果你有一个包含数字的字符串，可以使用`int`将其转化为整数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "d45e6a60",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42.0"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int('126') / 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "86935d56",
   "metadata": {},
   "source": [
    "如果你的字符串中包含数字和小数点，可以使用`float`将其转化为浮点数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "db30b719",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12.6"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float('12.6')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03103ef4",
   "metadata": {},
   "source": [
    "当你输入很大的整数，你可能想要用逗号作为数字的分隔符，比如`1,000,000`。在Python中这是合法的表达式，但结果并非整数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "d72b6af1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 0, 0)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1,000,000"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d24af71",
   "metadata": {},
   "source": [
    "Python将`1,000,000`解释为逗号分隔的整数序列。我们将在后面学习这种序列。\n",
    "\n",
    "你可以使用下划线让大数更加可读。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "e19bf7e7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1000000"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1_000_000"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1761cbac",
   "metadata": {},
   "source": [
    "## 形式语言与自然语言\n",
    "\n",
    "**自然语言**(Natural languages)是人们交流使用的语言，例如英语，西班牙语和法语。他们不是由人设计出来的，而是自然演变出来的。\n",
    "\n",
    "**形式语言**(Formal languages)是人类设计用于特定应用的语言。例如，数学记号是一种形式语言，对表示数字和符号之间的关系特别有用。类似的，编程语言是形式语言，用来表达计算步骤。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1bf3d2dc",
   "metadata": {},
   "source": [
    "尽管形式语言和自然语言有一些相同的特性，以下是重要的区别：\n",
    "\n",
    "- 模糊性：自然语言充满了模糊性，人们使用上下文和其他信息来进行处理。形式语言的设计目的是几乎或者完全没有模糊性，这意味着任何程序只有一种含义，与上下文无关。\n",
    "- 冗余性：为了弥补模糊性，减少误解，自然语言需要冗余，因此它们通常很啰嗦。形式语言更简洁。\n",
    "- 字面意义：自然语言充满了成语和隐喻。形式语言与它们表达的意思完全一致。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "78a1cec8",
   "metadata": {},
   "source": [
    "由于我们都在说自然语言的过程中长大，调整到形式语言有时很难。形式语言比自然语言的信息更密集，所以需要花更多时间阅读形式语言。\n",
    "\n",
    "译注：在之前章节关于`type是函数`的表述，体现了我们使用自然语言时不可避免的习惯。\n",
    "\n",
    "此外，结构很重要，从上到下，从左到右的阅读顺序并不总是最好的方式。\n",
    "\n",
    "最后，细节是重要的。拼写错误和标点符号的小错误在自然语言中可以理解，但在形式语言中可能导致巨大的差异。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4358fa9a",
   "metadata": {},
   "source": [
    "## 调试\n",
    "\n",
    "程序员会出错。出于心血来潮的原因，编程错误称为**故障bugs**，追踪它们的过程称为**调试**(debugging)。\n",
    "\n",
    "编程，尤其是调试，有时可能带来强烈的情感。如果你挣扎着处理一个困难的错误，你可能感觉愤怒，悲伤或者尴尬。\n",
    "\n",
    "对这些感情有准备可以帮助你处理它们。一种方法是将计算机看成有一定强项的职员，例如速度和精度，但在其他特定方面很弱，例如缺少同理心，不能顾全大局。\n",
    "\n",
    "你的工作是成为一个好经理：想办法利用计算机的强项，避免弱项。并且想办法利用你的情绪处理问题，而不要让情绪干扰你高效工作的能力。\n",
    "\n",
    "学习如何调试可能让人沮丧，但它对除了编程的许多活动都是珍贵的技能。在每章结尾有一节（像这一节）包含我对调试的建议。希望这些内容有用！"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33b8ad00",
   "metadata": {},
   "source": [
    "## 词汇表\n",
    "\n",
    "- **算术运算符arithmetic operator**:一种符号，表示算术运算，例如`+`和`*`表示加法和乘法。\n",
    "- **整数**：表示没有分数或小数部分的数字类型。\n",
    "- **浮点数floating-point**：表示有小数部分的整数。\n",
    "- **整数除法integer division**：`//`运算符，将两个数相除，向下取整。\n",
    "- **表达式expression**：变量，值和运算符的组合。\n",
    "- **值value**：一个整数，浮点数，字符串，或者之后将看到的其他类型的值。\n",
    "- **函数function**：一系列语句的组合的名字，执行一些有用的运算。函数可能接受或者不接受参数，可能产生或不产生结果。\n",
    "- **函数调用function call**：一个表达式（或者表达式的一部分），执行函数中的语句。函数调用由函数名，括号包围的参数列表组成。\n",
    "- **语法错误syntax error**：程序的一种错误，让Python无法理解，从而无法运行代码。\n",
    "- **字符串string**：表示字符序列的类型。\n",
    "- **拼接concatenation**：让两个字符串首尾连接。\n",
    "- **类型type**：值的一种分类方式。目前看到的类型包括整数(`int`)，浮点数(`float`)，字符串(`str`)类型。\n",
    "- **运算数，运算对象operand**：一个运算符运算的其中一个值。\n",
    "- **自然语言natural language**：自然演变出来的任何人类说的语言。\n",
    "- **形式语言formal language**：出于特殊目的设计出来的语言，例如用于表示数学概念或者计算机编程。所有的编程语言都是形式语言。\n",
    "- **漏洞，故障bug**：程序中的错误。\n",
    "- **调试debugging**：寻找并纠正错误的过程。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed4ec01b",
   "metadata": {},
   "source": [
    "## 练习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "06d3e72c",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Exception reporting mode: Verbose\n"
     ]
    }
   ],
   "source": [
    "# 这个单元格让Jupyter在出现运行时故障时提供更多调试信息。\n",
    "# 在进行练习前先运行本单元格。\n",
    "\n",
    "%xmode Verbose"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23adf208",
   "metadata": {},
   "source": [
    "### 询问虚拟助手\n",
    "\n",
    "当你学习这本书的时候，有几种方式可以让虚拟助手帮助你学习。\n",
    "\n",
    "- 如果你想要对章节中某个话题了解更多，或者有不清楚的地方，你可以让虚拟助手解释。\n",
    "- 如果你对任何练习有困难，你可以寻求帮助。\n",
    "\n",
    "在每一章，我建议你与虚拟助手一起完成练习，但我鼓励你先自己试试，看看哪种方式更好。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebf1a451",
   "metadata": {},
   "source": [
    "以下是一些话题，你可以询问虚拟助理：\n",
    "\n",
    "- 我先前提过位运算符，但没有解释为什么`7 ^ 2`的值为5。尝试问问“Python中的位运算符是什么？”，或者“`7 XOR 2`的值是什么？”\n",
    "- 我也提过运算符的顺序，想要更详细的解释，问问“Python中运算符的运算顺序是什么？”\n",
    "- `round`函数用于对浮点数取整，也能接受第2个参数。问问“Python中round的参数是什么？”，或者“我如何将Pi近似到3位小数？”\n",
    "- 有一个运算符我没有提到。问问“Python中的取模运算符是什么？”"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9be3e1c7",
   "metadata": {},
   "source": [
    "大多数虚拟助手知道Python，所以他们可能会给出十分可信的结果。但是记住，这些工具可能出错。如果你从虚拟助手获取了代码，测试它！"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03c1ef93",
   "metadata": {},
   "source": [
    "### 练习\n",
    "\n",
    "你可能好奇`round`如何对以`0.5`结尾的数字取整。它有时可能向上取整，有时可能向下。尝试以下例子，看看你能否发现它遵循的规则。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "5d358f37",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(42.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "12aa59a3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "44"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(43.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd2f890e",
   "metadata": {},
   "source": [
    "如果你感到好奇，询问虚拟助理，“如果一个数以0.5结尾，Python中的round函数将向下取整还是向上取整？\n",
    "\n",
    "译注： 小数以0.5结尾,round函数将取最近的偶数。这种取整行为是较为精确的“四舍六入五成双”修约规则。然而，由于浮点数无法精确表示许多小数的固有缺陷，有时会出现反例。询问虚拟助理，“在Python中，round(0.005,2)的结果是什么？”，或者“Python中，round(0.005,2)的结果为什么是0.01？”看看虚拟助理能否正确回答。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "3ab0ebcb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.01"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "round(0.005,2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2cd03bcb",
   "metadata": {},
   "source": [
    "### 练习\n",
    "\n",
    "在你学习新特性时，你应该进行尝试，并故意制造错误。在这种方式下，你能够学习错误信息，当你再次看到这些错误时，你将知道它们的含义。现在故意出错比以后意外出错要好。\n",
    "\n",
    "1. 你可以在数字前添加减号，表示负数，如`-2`。当你在数字前添加加号会发生什么？`2++2`又将发生什么？\n",
    "2. 如果你有两个值，但中间没有运算符，将发生什么？例如：`4 2`。\n",
    "3. 如果你调用函数（例如`round(42.5)`），丢掉一个或者两个括号将发生什么？"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1fb0adfe",
   "metadata": {},
   "source": [
    "### 练习\n",
    "\n",
    "回忆一下，每个表达式有一个值，每个值有一个类型，并且我们可以使用`type`找到任意值的类型。\n",
    "\n",
    "以下表达式的值的类型是什么？先猜测结果，然后使用`type`进行验证。\n",
    "\n",
    "* `765`\n",
    "\n",
    "* `2.718`\n",
    "\n",
    "* `'2 pi'`\n",
    "\n",
    "* `abs(-7)`\n",
    "\n",
    "* `abs(-7.0)`\n",
    "\n",
    "* `abs`\n",
    "\n",
    "* `int`\n",
    "\n",
    "* `type`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23762eec",
   "metadata": {},
   "source": [
    "### 练习\n",
    "\n",
    "以下结果可以让你练习算术表达式。\n",
    "\n",
    "1. 42分钟42秒是多少秒？\n",
    "2. 10公里是多少英里？提示：1英里是1.61公里。\n",
    "3. 如果用42分钟42秒跑完10公里，你的平均速度为多少英里每秒？\n",
    "4. 你每英里平均跑几分几秒？\n",
    "\n",
    "如果你已经知道了变量，你可以用他们进行练习。如果你还不知道，你可以不用变量就完成练习。下一章将介绍变量。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7f4edf8",
   "metadata": {
    "tags": []
   },
   "source": [
    "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n",
    "\n",
    "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n",
    "\n",
    "Code license: [MIT License](https://mit-license.org/)\n",
    "\n",
    "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
